#include "cmdthread.h"
#include <QProcess>
#include <QTextCodec>
#include <QByteArray>
#include <iostream>
using namespace std;

CmdThread::CmdThread(QString cmdstr, int outTimes, QString hostIP)
{
    this->isKilled = false;
    this->cmdstr   = cmdstr;
    this->outTimes = outTimes;
    this->hostIP   = hostIP;
    this->runTimes = 0;
    this->cmdStartTime = QDateTime::currentDateTime();
    QStringList options;
    options << "-c";
    options << cmdstr;
    cmdgExec.start("/bin/bash", options);
}

QString CmdThread::GetCmdstr()
{
    return this->cmdstr;
}

QString CmdThread::GetCmdOutstr()
{
    QString retstr;
    cmdMutex.lock();
    retstr = cmdOutstr;
    cmdOutstr.clear();
    cmdMutex.unlock();
    return retstr;
}

QString CmdThread::GetHostIP()
{
    return this->hostIP;
}

int CmdThread::GetRumTimes()
{
    return this->runTimes;
}

QString CmdThread::GetErrstr()
{
    return this->cmdErrstr;
}

void CmdThread::killRun()
{
    this->isKilled = true;
}

void CmdThread::run()
{
    QByteArray debugDatagram;
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    debugDatagram = QString("Info: cmd<%1> start runing.").arg(cmdstr).toLatin1();
    cout << debugDatagram.data() << endl;
    
    QTime timeCount;
    timeCount.start();
    while (true) {
        msleep(500);
        QString outstr = codec->toUnicode(cmdgExec.readAllStandardOutput());  //读取运行过程中的输出值
        outstr.append(codec->toUnicode(cmdgExec.readAllStandardError()));
        cmdMutex.lock();
        cmdOutstr.append(outstr);
        cmdMutex.unlock();
        if(cmdOutstr.length() >= 64){
            emit cmdStatChanged(cmdstr, CMD_RUNING);
        }
        if(outstr.length() != 0){
            debugDatagram = outstr.toUtf8();
            cout << debugDatagram.data();
        }
        this->runTimes = QDateTime::currentDateTime().toTime_t() - cmdStartTime.toTime_t();
        if(this->runTimes  > this->outTimes){       // 运行时间超时
            if(timeCount.elapsed() > 10*1000){      // 10 s发送一次
                timeCount.start();
                emit cmdStatChanged(cmdstr, CMD_TIMEOUT);
            }
        }
        if(cmdgExec.state() == QProcess::NotRunning){
            if(cmdOutstr.length() > 0){
                emit cmdStatChanged(cmdstr, CMD_RUNING);
                msleep(1000);
            }
            break;
        }
        if(isKilled){
            cmdgExec.kill();
        }
    }
    if(cmdgExec.exitStatus() == QProcess::CrashExit){
        cmdErrstr = cmdgExec.errorString();
        debugDatagram = QString("Err: cmd<%1> crash<%2> ended!!!").arg(cmdstr).arg(cmdErrstr).toLatin1();
        cout << endl << debugDatagram.data() << endl;
        emit cmdStatChanged(cmdstr, CMD_CRASHEND);
    }else{
        debugDatagram = QString("Info: cmd<%1> run ended.").arg(cmdstr).toLatin1();
        cout << endl << debugDatagram.data() << endl;
        emit cmdStatChanged(cmdstr, CMD_END);
    }
}
